package com.tkk.monitoring.analyze.exp.xss;

import com.tkk.monitoring.analyze.AnalyzeTarget;
import com.tkk.monitoring.analyze.AnalyzeWorker;
import com.tkk.monitoring.analyze.config.Line;
import com.tkk.monitoring.analyze.db.DB;
import com.tkk.monitoring.analyze.http.Session;
import org.apache.commons.lang.StringUtils;

import java.util.HashMap;
import java.util.Set;

/**
 * author: Tkk
 * date: 2015/7/8
 * <p/>
 * 遍历每个参数, 每次都进行改变
 */
public class XSSAnalyzeWorker extends AnalyzeWorker {

    private static final Line line = new Line("xss.txt");

    public XSSAnalyzeWorker(AnalyzeTarget target) {
        super(target);
    }

    /**
     *
     */
    @Override
    public void run() {
        //
        if (target.hasParam()) {
            Session session = new Session(target.getUri(), target.getMethod(), target.getHeaders());
            try {
                for (String poc : line.getLines()) {
                    check(session, poc);
                }
            } finally {
                session.close();
            }
        }
        //
        else {

        }
    }

    private void check(Session session, String poc) {
        //
        HashMap<String, Object> paramMap = target.getGetParam();
        HashMap<String, Object> paramMap2 = target.getPostParam();
        String uri = target.getUri();

        //检测get参数
        if (paramMap != null) {
            Set<String> paramNames = paramMap.keySet();
            for (String paramName : paramNames) {
                HashMap<String, Object> cloneMap = (HashMap<String, Object>) paramMap.clone();
                cloneMap.put(paramName, poc);
                String responseContent = null;

                //如果是post, 那么重新生成url, 并且用post的参数去请求
                if (target.getMethod().equals("post")) {
                    String url = session.toURL(uri, cloneMap);
                    session.setUri(url);
                    session.content(paramMap2);
                }
                //如果是get, 那么直接调用
                else {
                    responseContent = session.content(cloneMap);
                }
                analyze(responseContent, paramName, poc);
            }
        }

        if (paramMap2 != null) {
            String url = session.toURL(uri, paramMap);
            session.setUri(url);
            Set<String> paramNames = paramMap2.keySet();
            for (String paramName : paramNames) {
                HashMap<String, Object> cloneMap = (HashMap<String, Object>) paramMap2.clone();
                cloneMap.put(paramName, poc);
                String responseContent = session.content(cloneMap);
                analyze(responseContent, paramName, poc);
            }
        }
    }

    /**
     * @param responseContent
     * @param paramName
     * @param paramValue
     */
    private void analyze(String responseContent, String paramName, String paramValue) {
        String uri = target.getUri();
        if (StringUtils.isNotBlank(responseContent) && responseContent.indexOf(paramValue) != -1) {
            logger.info(String.format("站点:[%s] 路径:[%s] 参数:%s poc:%s 类型:xss 结果:yes", uri, target.getUrl(), paramName, paramValue));
            DB.getInstance().addPoc("XSS注入", target.getUrl(), responseContent, String.format("参数:%s poc:%s", paramName, paramValue));
        } else {
            logger.info(String.format("站点:[%s] 路径:[%s] 参数:%s poc:%s 类型:xss 结果:no", uri, target.getUrl(), paramName, paramValue));
        }
    }
}
